from general_utilities import *
from graphics_utilities import *
from map import *
from glyphs import *
from sound import *

def GuilessDialog(title,image,text,chars_per_line,button_names,hotkeys,is_fullscreen=0,allow_quit=0):
    # button_names is a [string] of length at least 1
    # hotkeys is a [string] of the same length, or None
    # return value is an element of button_names
    # press Enter to choose the first button (which should be highlit)
    temp_surface = pygame.Surface((display.total_width,display.total_height))
    temp_surface.blit(display.screen,(0,0))
    n_buttons = len(button_names)
    separated_text = break_long_string(text,chars_per_line)
    offset_down = 0
    offset_right = 0
    header_and_button_rects = redraw_box_for_guilessdialog(title,image,separated_text,chars_per_line,button_names,offset_down,offset_right)
    header_rect = header_and_button_rects[0]
    button_rects = header_and_button_rects[1]
    pygame.display.flip()
    result = ''
    finished = 0
    dragging = 0
    dragging_from = None
    while(not finished):
        skip_mousemotions = 0
        events = pygame.event.get()
        for event in events:
            if event.type==KEYDOWN:
                if event.key==K_KP_ENTER or event.key==K_RETURN:
                    result = button_names[0]
                    finished = 1
                elif hotkeys is not None:
                    for i in range(n_buttons):
                        if event.unicode == hotkeys[i]:
                            result = button_names[i]
                            finished = 1
                            break
            elif event.type==MOUSEMOTION and dragging and not skip_mousemotions:
                display.screen.blit(temp_surface,(0,0))
                offset_down = offset_down - (event.pos[1]-dragging_from[1])
                offset_right = offset_right - (event.pos[0]-dragging_from[0])
                dragging_from = event.pos
                header_and_button_rects = redraw_box_for_guilessdialog(title,image,separated_text,chars_per_line,button_names,offset_down,offset_right)
                header_rect = header_and_button_rects[0]
                button_rects = header_and_button_rects[1]
                pygame.display.flip()                
                if is_fullscreen:
                    skip_mousemotions = 1
            elif event.type==MOUSEBUTTONDOWN and not dragging and header_rect.collidepoint(event.pos): 
                dragging = 1
                dragging_from = event.pos
            elif event.type==MOUSEBUTTONUP:
                if dragging:
                    dragging = 0
                else:
                    for i in range(n_buttons):
                        if button_rects[i].collidepoint(event.pos): 
                            result = button_names[i]
                            finished = 1
                            break
            elif event.type==QUIT and allow_quit:
                raise SystemExit
    display.screen.blit(temp_surface,(0,0))
    pygame.display.flip()
    return result

def redraw_box_for_guilessdialog(title,image,separated_text,chars_per_line,button_names,offset_down,offset_right):
    header = display.message_font.render(title, 1, yellow)
    header_top = 1
    header_bottom = 22
    image_top = header_bottom+10
    if image is not None:
        image_bottom = image_top + image.get_height() + 20
    else:
        image_bottom = image_top
    text_top = image_bottom + 10
    text_bottom = text_top + 21*len(separated_text) + 20
    max_button_text_length = 0
    for name in button_names:
        blitted_text = display.message_font.render(name, 1, black)
        max_button_text_length = max(max_button_text_length,blitted_text.get_width())
    button_width = max(60,max_button_text_length+10)
    button_height = 22
    n_buttons = len(button_names)
    button_rows = 1+n_buttons/3
    button_rows_tops = []
    for i in range(button_rows):
        button_rows_tops.append(text_bottom + 5 + (button_height+5)*i)
    buttons_bottom = text_bottom + 5 + (button_height+5)*button_rows
    box_height = buttons_bottom + 20
    box_width = 460 + max(0,button_width-80)*3
    box_padding_ud = (display.total_height - box_height) / 2 - offset_down
    box_padding_lr = (display.total_width - box_width) / 2 - offset_right
    box_rect = Rect(box_padding_lr,box_padding_ud,box_width,box_height)
    pygame.draw.rect(display.screen, light_grey, box_rect)
    pygame.draw.rect(display.screen, black, box_rect, 1)
    pygame.draw.line(display.screen, white, (box_rect.left+1,box_rect.bottom-1), (box_rect.left+1,box_rect.top+1), 1)
    pygame.draw.line(display.screen, white, (box_rect.left+1,box_rect.top+1), (box_rect.right-1,box_rect.top+1), 1)
    pygame.draw.line(display.screen, dark_grey, (box_rect.left+1,box_rect.bottom-1), (box_rect.right-1,box_rect.bottom-1), 1)
    pygame.draw.line(display.screen, dark_grey, (box_rect.right-1,box_rect.bottom-1), (box_rect.right-1,box_rect.top+1), 1)   
    center_line = display.total_width / 2 - offset_right
    header_rect = Rect(box_padding_lr+2,header_top+box_padding_ud+1,box_width-4,header_bottom-header_top-2)
    pygame.draw.rect(display.screen, dark_grey, header_rect)
    #pygame.draw.line(display.screen, white, (header_rect.left,header_rect.bottom-1), (header_rect.left,header_rect.top+1), 1)
    #pygame.draw.line(display.screen, white, (header_rect.left,header_rect.top+1), (header_rect.right,header_rect.top+1), 1)
    #pygame.draw.line(display.screen, light_grey, (header_rect.left+1,header_rect.bottom-1), (header_rect.right-1,header_rect.bottom-1), 1)
    #pygame.draw.line(display.screen, light_grey, (header_rect.right-1,header_rect.bottom-1), (header_rect.right-1,header_rect.top+1), 1)   
    display.screen.blit(header,(box_padding_lr+5,header_top+box_padding_ud))
    if image is not None:
        image_padding_lr = (box_width-image.get_width())/2
        display.screen.blit(image,(box_rect.left+image_padding_lr,image_top+box_padding_ud))
    for i in range(len(separated_text)):
        line = separated_text[i]
        blitted_text = display.message_font.render(line, 1, black)
        text_padding_lr = (box_width-blitted_text.get_width())/2
        display.screen.blit(blitted_text,(box_rect.left+text_padding_lr,text_top+box_padding_ud+i*20))
    button_xs = [0] * n_buttons # -1 to 1
    button_ys = [0] * n_buttons # 0 to button_rows-1
    if n_buttons==1:
        button_xs[0] = 0
        button_ys[0] = 0
    elif n_buttons==2:
        button_xs[0] = -1
        button_ys[0] = 0
        button_xs[1] = 1
        button_ys[1] = 0
    else:
        for i in range(n_buttons):
            button_xs[i] = i % 3 - 1
            button_ys[i] = i / 3
    button_rects = [] 
    for i in range(n_buttons):
        this_rect = Rect(center_line-button_width/2+max(button_width*1.2,100)*button_xs[i],button_rows_tops[button_ys[i]]+box_padding_ud,button_width,button_height)
        button_rects.append(this_rect)
        if i==0:
            pygame.draw.line(display.screen, white, (this_rect.left+1,this_rect.bottom-1), (this_rect.left+1,this_rect.top+1), 1)
            pygame.draw.line(display.screen, white, (this_rect.left+1,this_rect.top+1), (this_rect.right-1,this_rect.top+1), 1)
            pygame.draw.line(display.screen, dark_grey, (this_rect.left+1,this_rect.bottom-1), (this_rect.right-1,this_rect.bottom-1), 1)
            pygame.draw.line(display.screen, dark_grey, (this_rect.right-1,this_rect.bottom-1), (this_rect.right-1,this_rect.top+1), 1) 
            pygame.draw.rect(display.screen, black, this_rect, 1) 
        else:
            pygame.draw.line(display.screen, white, (this_rect.left,this_rect.bottom), (this_rect.left,this_rect.top), 1)
            pygame.draw.line(display.screen, white, (this_rect.left,this_rect.top), (this_rect.right,this_rect.top), 1)
            pygame.draw.line(display.screen, dark_grey, (this_rect.left,this_rect.bottom), (this_rect.right,this_rect.bottom), 1)
            pygame.draw.line(display.screen, dark_grey, (this_rect.right,this_rect.bottom), (this_rect.right,this_rect.top), 1)                              
        blitted_text = display.message_font.render(button_names[i], 1, black)
        text_padding_lr = (button_width-blitted_text.get_width())/2
        display.screen.blit(blitted_text,(this_rect.left+text_padding_lr,this_rect.top))   
    return header_rect, button_rects

def GuilessFileChooser(question,startpath,can_cancel,is_fullscreen=0,allow_quit=0):
    # startpath is *relative*
    # returns a filename or None
    possibles = []
    files = os.listdir(startpath)
    for file in files:
        if file.endswith('.sav'):
            possibles.append(file[0:-4])
    if can_cancel:
        possibles.append('Cancel')
    file_chosen = GuilessDialog('Choose a savefile',None,question,70,possibles,None,is_fullscreen=is_fullscreen,allow_quit=allow_quit)
    if file_chosen=='Cancel':
        return None
    return startpath+"/"+file_chosen+".sav"

def GuilessSplashScreen(image,separated_text,stop_immediately=0,allow_quit=0):
    # image can be None
    # separated_text is a vector of strings
    # returns nothing, and does not redraw the screen before exiting
    display.screen.fill(black)
    if image is not None:
        display.screen.blit(image,(0,0))
    line_height = 21
    padding_ud = (display.total_height - len(separated_text)*line_height)/2
    for i in range(len(separated_text)):
        line = separated_text[i]
        blitted_text = display.message_font.render(line, 1, yellow)
        line_width = blitted_text.get_width()
        padding_rl = (display.total_width - line_width)/2
        display.screen.blit(blitted_text,Rect(padding_rl,padding_ud+line_height*i,line_width,line_height))
    pygame.display.flip()
    while(1):
        if stop_immediately:
            return
        events = pygame.event.get()
        for event in events:
            if event.type==QUIT and allow_quit:
                sys.exit(0)
            if event.type==QUIT or event.type==KEYDOWN or event.type==MOUSEBUTTONUP:
                return

def GuilessInputDialog(title,question,image=None,is_fullscreen=0,allow_quit=0):
    # returns a string (can be '')
    temp_surface = pygame.Surface((display.total_width,display.total_height))
    temp_surface.blit(display.screen,(0,0))
    answer = ''
    finished = 0
    dragging = 0
    dragging_from = None
    offset_right = 0
    offset_down = 0
    while(not finished):
        header = display.message_font.render(title, 1, yellow)
        header_top = 1
        header_bottom = 22
        image_top = header_bottom+10
        if image is not None:
            image_bottom = image_top + image.get_height() + 20
        else:
            image_bottom = image_top
        text_top = image_bottom + 10
        text_bottom = text_top + 41
        box_height = text_bottom + 60
        box_width = 460
        box_padding_ud = (display.total_height - box_height) / 2 - offset_down
        box_padding_lr = (display.total_width - box_width) / 2 - offset_right
        box_rect = Rect(box_padding_lr,box_padding_ud,box_width,box_height)
        pygame.draw.rect(display.screen, light_grey, box_rect)
        pygame.draw.line(display.screen, white, (box_rect.left+1,box_rect.bottom-1), (box_rect.left+1,box_rect.top+1), 1)
        pygame.draw.line(display.screen, white, (box_rect.left+1,box_rect.top+1), (box_rect.right-1,box_rect.top+1), 1)
        pygame.draw.line(display.screen, dark_grey, (box_rect.left+1,box_rect.bottom-1), (box_rect.right-1,box_rect.bottom-1), 1)
        pygame.draw.line(display.screen, dark_grey, (box_rect.right-1,box_rect.bottom-1), (box_rect.right-1,box_rect.top+1), 1)   
        center_line = display.total_width / 2 - offset_right
        header_rect = Rect(box_padding_lr+2,header_top+box_padding_ud+1,box_width-4,header_bottom-header_top-2)
        pygame.draw.rect(display.screen, dark_grey, header_rect)
        #pygame.draw.line(display.screen, white, (header_rect.left,header_rect.bottom-1), (header_rect.left,header_rect.top+1), 1)
        #pygame.draw.line(display.screen, white, (header_rect.left,header_rect.top+1), (header_rect.right,header_rect.top+1), 1)
        #pygame.draw.line(display.screen, light_grey, (header_rect.left+1,header_rect.bottom-1), (header_rect.right-1,header_rect.bottom-1), 1)
        #pygame.draw.line(display.screen, light_grey, (header_rect.right-1,header_rect.bottom-1), (header_rect.right-1,header_rect.top+1), 1)   
        display.screen.blit(header,(box_padding_lr+5,header_top+box_padding_ud))
        if image is not None:
            image_padding_lr = (box_width-image.get_width())/2
            display.screen.blit(image,(box_rect.left+image_padding_lr,image_top+box_padding_ud))
        blitted_text = display.message_font.render(question + ":  " + answer, 1, black)
        display.screen.blit(blitted_text,(box_rect.left+10,text_top+box_padding_ud))
        button_width = 60
        button_height = 22
        ok_button_rect = Rect(center_line-button_width/2,box_rect.top+text_bottom+20,button_width,button_height)
        pygame.draw.line(display.screen, white, (ok_button_rect.left+1,ok_button_rect.bottom-1), (ok_button_rect.left+1,ok_button_rect.top+1), 1)
        pygame.draw.line(display.screen, white, (ok_button_rect.left+1,ok_button_rect.top+1), (ok_button_rect.right-1,ok_button_rect.top+1), 1)
        pygame.draw.line(display.screen, dark_grey, (ok_button_rect.left+1,ok_button_rect.bottom-1), (ok_button_rect.right-1,ok_button_rect.bottom-1), 1)
        pygame.draw.line(display.screen, dark_grey, (ok_button_rect.right-1,ok_button_rect.bottom-1), (ok_button_rect.right-1,ok_button_rect.top+1), 1) 
        pygame.draw.rect(display.screen, black, ok_button_rect, 1) 
        blitted_text = display.message_font.render('OK', 1, black)
        text_padding_lr = (button_width-blitted_text.get_width())/2
        display.screen.blit(blitted_text,(ok_button_rect.left+text_padding_lr,ok_button_rect.top))
        pygame.display.flip()
        events = pygame.event.get()
        skip_mousemotions = 0
        for event in events:
            if event.type==KEYDOWN:
                if event.key==K_KP_ENTER or event.key==K_RETURN:
                    finished = 1
                    break
                elif event.key==K_BACKSPACE:
                    answer = answer[0:-1]
                elif (event.unicode >= 'a' and event.unicode <= 'z') or (event.unicode >= 'A' and event.unicode <= 'Z') or event.unicode in ('0','1','2','3','4','5','6','7','8','9'):
                    answer = answer + chr(event.key)
            elif event.type==MOUSEMOTION and dragging and not skip_mousemotions:
                display.screen.blit(temp_surface,(0,0))
                offset_down = offset_down - (event.pos[1]-dragging_from[1])
                offset_right = offset_right - (event.pos[0]-dragging_from[0])
                dragging_from = event.pos             
                if is_fullscreen:
                    skip_mousemotions = 1
            elif event.type==MOUSEBUTTONDOWN and not dragging and header_rect.collidepoint(event.pos): 
                dragging = 1
                dragging_from = event.pos
            elif event.type==MOUSEBUTTONUP:
                if dragging:
                    dragging = 0
                else:
                    if ok_button_rect.collidepoint(event.pos): 
                        finished = 1
                        break
            elif event.type==QUIT and allow_quit:
                raise SystemExit
        if finished:
            break
    display.screen.blit(temp_surface,(0,0))
    pygame.display.flip()
    return answer

def break_long_string(text,chars_per_line):
    text_array = []
    count = 0
    line = ""
    for char in text:
        if char=='\n':
            count = chars_per_line
        else:
            count = count + 1
            line = line + char
        if count>=chars_per_line and (char==' ' or char=='\n'):
            text_array.append(line)
            line = ""
            count = 0
    text_array.append(line)  
    return text_array
    
class MapPane:
    def __init__(self,width,height,top,left,iconsize):
        self.view = pygame.Surface((width,height))
        self.view.fill(black)
        self.top = top
        self.left = left
        self._width = width
        self._height = height
        self.iconsize = iconsize

class MessagePane:
    def __init__(self,rect,slider_rect):
        self.interior_height = 2000
        self.interior = pygame.Surface((rect.width-8,self.interior_height)) 
        self.interior.fill(black)
        self.temp_surface = pygame.Surface((rect.width-8,self.interior_height)) 
        self.top = rect.top+4
        self.left = rect.left+4
        self._width = rect.width-8
        self._height = rect.height-8
        self.max_y_used = 0
        self.slider_rect = slider_rect
        self.scroll_to_bottom()
        
    def scroll_to_top(self):
        self.scroll_to_percent(0)
        
    def scroll_to_bottom(self):
        self.scroll_to_percent(100)
        
    def scroll_to_percent(self,percent):
        # 100 is bottom, 0 is top
        highest = self.get_highest_offset()
        lowest = self.get_lowest_offset()
        self.offset = int(floor((percent/100.0) * (lowest - highest) + highest))
        percent_range = self.get_current_percent_range()
        yrange = (self.slider_rect.top + int(floor(self.slider_rect.height * percent_range[0] / 100.0)),self.slider_rect.top + int(floor(self.slider_rect.height * percent_range[1] / 100.0)))
        self.slider_box_rect = Rect(self.slider_rect.left,yrange[0]+1,self.slider_rect.width,yrange[1]-yrange[0]-2)

    def scroll_up(self,amount):
        self.offset = max(self.offset-amount,self.get_highest_offset())
        percent_range = self.get_current_percent_range()
        yrange = (self.slider_rect.top + int(floor(self.slider_rect.height * percent_range[0] / 100.0)),self.slider_rect.top + int(floor(self.slider_rect.height * percent_range[1] / 100.0)))
        self.slider_box_rect = Rect(self.slider_rect.left,yrange[0]+1,self.slider_rect.width,yrange[1]-yrange[0]-2)

    def scroll_down(self,amount):
        self.offset = min(self.offset+amount,self.get_lowest_offset())
        percent_range = self.get_current_percent_range()
        yrange = (self.slider_rect.top + int(floor(self.slider_rect.height * percent_range[0] / 100.0)),self.slider_rect.top + int(floor(self.slider_rect.height * percent_range[1] / 100.0)))
        self.slider_box_rect = Rect(self.slider_rect.left,yrange[0]+1,self.slider_rect.width,yrange[1]-yrange[0]-2)

    def get_current_percent_range(self):
        # return a 2-vector of percentiles in view
        highest = self.get_highest_offset()
        lowest = self.get_lowest_offset()
        if lowest==highest:
            return (0,100)
        return (100 * float(self.offset - highest)/(self.interior_height-highest),100 * float(self.offset + self._height - 10 - highest)/(self.interior_height-highest))

    def get_highest_offset(self):
        return max(0, min(self.interior_height - self._height + 10,self.interior_height - self.max_y_used))

    def get_lowest_offset(self):
        return self.interior_height - self._height + 10
            
    def draw(self):
        display.screen.fill(black,Rect(self.left-4,self.top-4,self._width+8,self._height+8))
        display.screen.blit(self.interior,(self.left,self.top),Rect(0,self.offset,self._width,self._height))
        display.screen.fill(white,self.slider_rect)
        pygame.draw.rect(display.screen, black, self.slider_rect)
        pygame.draw.rect(display.screen, dark_grey, self.slider_box_rect)
        pygame.display.flip()
        
    def show_message(self,separated_text,color):
        message_images = []
        total_height = 11
        for text in separated_text:
            this_image = display.message_font.render(text, 1, color)
            message_images.append(this_image)
            total_height = total_height + this_image.get_height() - 5
        self.temp_surface.blit(self.interior,(0,0),Rect(0,total_height,self._width,self.interior_height))
        self.interior.blit(self.temp_surface,(0,0),Rect(0,0,self._width,self.interior_height-total_height))
        self.interior.fill(black,Rect(0,self.interior_height-total_height,self._width,total_height))
        y = self.interior_height - total_height + 1
        for image in message_images:
            self.interior.blit(image,(0,y))
            y = y + image.get_height() - 5
        pygame.draw.line(self.interior,color,(20,y+8),(self._width-40,y+8))
        self.max_y_used = min(self.max_y_used + total_height, self.interior_height)
        self.scroll_to_bottom()
        self.draw()
        
class Screen_info:
    def initialise(self,fullscreen):
        # initialize pygame
        pygame.init()    
        pygame.key.set_repeat(100, 100) # keyboard repeat rate
        # create message font 
        self.message_fontsize = 14
        self.message_fontname = 'data/sylfaen.ttf'
        self.message_font = pygame.font.Font(self.message_fontname, self.message_fontsize) 
        self.smaller_message_font = pygame.font.Font(self.message_fontname, self.message_fontsize-3) 
        # create, resize and blank display
        self.create_screen(1024,768,'OrbQuest',fullscreen) # was 950,737
        # load tiles
        self.gervais_tiles = load_image("32x32.bmp")
        self.new_tiles = load_image("new 32x32.bmp")
        self.minimap_tiles = load_image("minimap.bmp")
        self.iconsize = 32
        self.minimap_iconsize = 5
        # define role images
        self.role_images = {R_PEASANT:get_tile(self.gervais_tiles,self.iconsize,9,11,black), \
R_WARRIOR:get_tile(self.gervais_tiles,self.iconsize,7,11,black), \
R_ROGUE:get_tile(self.gervais_tiles,self.iconsize,10,4,black), \
R_PRIEST:colorchange(get_tile(self.gervais_tiles,self.iconsize,4,3,black),green,white), \
R_MAGE:get_tile(self.gervais_tiles,self.iconsize,18,3,black), \
R_WARLOCK:colorchange(get_tile(self.gervais_tiles,self.iconsize,0,4,black),green,purple), \
R_CRUSADER:get_tile(self.gervais_tiles,self.iconsize,39,4,black), \
R_UNDEAD_SLAYER:get_tile(self.gervais_tiles,self.iconsize,8,13,black), \
R_TRICKSTER:get_tile(self.gervais_tiles,self.iconsize,4,11,black), \
}
        # add background to display
        self.background = load_image("background.bmp")
        self.need_to_blit = 0 # set this to 1 if you need the screen reblitted, which will set it back to 0
        # define rectangles
        self.map_rect = Rect(16,16,self.iconsize*MAP_WIDTH+1,self.iconsize*MAP_HEIGHT+1)
        self.garb_rect = Rect(787,184,1*self.iconsize,1*self.iconsize)
        self.melee_weapon_rect = Rect(787,220,1*self.iconsize,1*self.iconsize)
        self.missile_weapon_rect = Rect(787,256,1*self.iconsize,1*self.iconsize)
        self.item_rects = [None, None, None, None, None, None]
        for i in range(3):
            self.item_rects[i] = Rect(855,i*36+184,1*self.iconsize,1*self.iconsize)
            self.item_rects[i+3] = Rect(891,i*36+184,1*self.iconsize,1*self.iconsize)
        self.key_rects = [None, None, None, None, None]
        for i in range(5):
            self.key_rects[i] = Rect(787+i*28,301,24,24)
        self.hp_rect = Rect(955,70,8,183)
        self.mp_rect = Rect(969,70,8,183)
        self.energy_rect = Rect(983,70,8,183)
        self.message_rect = Rect(766,366,228,386) 
        self.slider_rect = Rect(998,366,10,386)
        self.new_rect = Rect(786,67,37,17) 
        self.load_rect = Rect(835,67,39,17)
        self.quit_rect = Rect(887,67,37,17)       
        self.minimap_rect = Rect(786,98,47,22)
        self.powers_rect = Rect(848,98,76,22)
        self.score_rect = Rect(950,309,44,18) 
        # add map pane to display
        self.map = MapPane(width=self.map_rect.width,height=self.map_rect.height,left=self.map_rect.left,top=self.map_rect.top,iconsize=self.iconsize)
        # and message pane
        self.message_area = MessagePane(self.message_rect,self.slider_rect)
        # create character tile
        self.character_tile = None # we will fill this in later
        self.black_tile = self.get_tile("gervais",20,11)
        self.black_tile.set_colorkey(None)
        self.dark_grey_tile = lighten(self.get_tile("gervais",20,11),0.3,except_col=None)
        self.dark_grey_tile.set_colorkey(None)
        self.big_black_tile = scale_up_by(self.black_tile,2)
        self.minimap_tile = self.get_minimap_tile(0,0)
        self.minimap_monster_tile = self.get_minimap_tile(14,0)
        self.minimap_character_tile = self.get_minimap_tile(23,0)
        self.minimap_object_tile = self.get_minimap_tile(17,0)
        self.minimap_statue_tile = self.get_minimap_tile(1,0)
        # create effects
        self.flash = self.get_tile("gervais",99,1)
        self.thump = self.get_tile("gervais",48,1)
        self.defend = self.get_tile("gervais",93,0)
        self.arrow = self.get_tile("gervais",112,1)
        self.firebolt = self.get_tile("gervais",14,1)
        self.lightning = self.get_tile("gervais",93,1)
        self.stone = self.get_tile("gervais",54,10)
        self.yellowstars = self.get_tile("gervais",66,1)
        self.confuse = self.get_tile("gervais",43,18)
        self.darkflash = self.get_tile("gervais",71,1)
        self.darkvortex = self.get_tile("gervais",44,18)
        self.bible = self.get_tile('gervais',17,6)
        self.zap = self.get_tile('gervais',2,1)
        self.bigthump = self.get_tile('gervais',102,1)
        self.firearrow = self.get_tile('gervais',93,10)
        self.fire = self.get_tile('gervais',79,23)
        self.badbook = self.get_tile('gervais',8,6)
        self.misc_skeleton = self.get_tile('gervais',46,7)
        self.broken_bone = self.get_tile('gervais',44,7)
        self.animal_skeleton = self.get_tile('gervais',49,7)
        self.warning = self.get_tile('gervais',79,1)
        self.temple = self.get_tile('gervais',70,27)
        self.greenframe = self.get_tile('new',2,5)
        self.goldstars = self.get_tile('new',7,7)
        self.redstars = self.get_tile('new',7,8)
        # Stars
        self.one_star = load_image("onestar.bmp")
        self.one_star.set_colorkey(black)
        self.two_stars = load_image("twostars.bmp")
        self.two_stars.set_colorkey(black)
        self.three_stars = load_image("threestars.bmp")
        self.three_stars.set_colorkey(black)
        # Buttons
        self.fullscreenise = load_image("fullscreenise.bmp")
        self.iconify = load_image("iconify.bmp")
        self.windowise = load_image("windowise.bmp")
        self.quit = load_image("quit.bmp")
        self.mute = load_image("mute.bmp")
        self.soundon = load_image("soundon.bmp")
        self.uparrow = load_image("uparrow.bmp")
        self.downarrow = load_image("downarrow.bmp")
        # Terrain underlays
        self.tile_floor_underlays = {} # keyed by F_ code, value is image
        self.tile_floor_underlays[F_ORDINARY] = self.get_tile("gervais",7,23)
        self.tile_floor_underlays[F_ORDINARY_DARK] = darken(self.get_tile("gervais",7,23),0.25)
        self.tile_floor_underlays[F_COBBLES] = self.get_tile("gervais",0,22)
        self.tile_floor_underlays[F_COBBLES_DARK] = self.get_tile("gervais",104,24)
        self.tile_floor_underlays[F_OTHER_COBBLES] = self.get_tile("new",8,4)
        self.tile_floor_underlays[F_FLECKS] = self.get_tile("new",8,5)
        self.tile_floor_underlays[F_ROCK] = self.get_tile("gervais",58,22)
        self.tile_floor_underlays[F_EARTH] = self.get_tile("gervais",13,23)
        self.tile_floor_underlays[F_MOSSY] = self.get_tile("gervais",51,22)
        self.tile_floor_underlays[F_WITH_MAGMA] = self.get_tile("gervais",34,23)
        # create terrains
        self.terrains = {} # indexed by (T_ code, W_ code, F_ code)
        self.minimap_terrains = {}
        for f_code in range(0,F_LAST):
            for w_code in range(0,W_LAST):
                self.terrains[(T_FIRE_PIT,w_code,f_code)] = self.get_tile("gervais",80,23)
                self.minimap_terrains[T_FIRE_PIT] = self.get_minimap_tile(18,0)  
                self.terrains[(T_WATER,w_code,f_code)] = self.get_tile("new",1,5) # self.get_tile("gervais",19,23)
                self.minimap_terrains[T_WATER] = self.get_minimap_tile(20,0)        
                self.terrains[(T_WATER_WALL,w_code,f_code)] = self.get_tile("new",1,5) # self.get_tile("gervais",19,23)
                self.minimap_terrains[T_WATER_WALL] = self.get_minimap_tile(20,0)        
                # now things that depend on floor
                self.terrains[(T_FLOOR,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_FLOOR,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))              
                self.minimap_terrains[T_FLOOR] = self.get_minimap_tile(0,0)
                self.terrains[(T_FLOOR_NOTELEPORT,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_FLOOR_NOTELEPORT,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))              
                self.minimap_terrains[T_FLOOR_NOTELEPORT] = self.get_minimap_tile(0,0)
                self.terrains[(T_PIT,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_PIT,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))              
                self.terrains[(T_PIT,w_code,f_code)].blit(self.get_tile("new",3,4),(0,0))
                self.minimap_terrains[T_PIT] = self.get_minimap_tile(15,0)                
                self.terrains[(T_RUNE_TELEPORT,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_RUNE_TELEPORT,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))              
                self.terrains[(T_RUNE_TELEPORT,w_code,f_code)].blit(self.get_tile("gervais",41,7),(0,0))
                self.minimap_terrains[T_RUNE_TELEPORT] = self.get_minimap_tile(0,0)
                self.terrains[(T_RUNE_CONFUSION,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_RUNE_CONFUSION,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))              
                self.terrains[(T_RUNE_CONFUSION,w_code,f_code)].blit(self.get_tile("gervais",40,7),(0,0))
                self.minimap_terrains[T_RUNE_CONFUSION] = self.get_minimap_tile(0,0)
                self.terrains[(T_RUNE_PAIN,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_RUNE_PAIN,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))              
                self.terrains[(T_RUNE_PAIN,w_code,f_code)].blit(self.get_tile("gervais",39,7),(0,0))
                self.minimap_terrains[T_RUNE_PAIN] = self.get_minimap_tile(0,0)
                self.terrains[(T_CAMPFIRE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_CAMPFIRE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_CAMPFIRE,w_code,f_code)].blit(self.get_tile("new",6,2),(0,0))
                self.minimap_terrains[T_CAMPFIRE] = self.get_minimap_tile(18,0)
                self.terrains[(T_WEB,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_WEB,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_WEB,w_code,f_code)].blit(self.get_tile("new",7,2),(0,0))
                self.minimap_terrains[T_WEB] = self.get_minimap_tile(19,0)
                self.terrains[(T_BOOKCASE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_BOOKCASE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_BOOKCASE,w_code,f_code)].blit(self.get_tile("new",2,2),(0,0))
                self.minimap_terrains[T_BOOKCASE] = self.get_minimap_tile(1,0)
                self.terrains[(T_DESK,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_DESK,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_DESK,w_code,f_code)].blit(self.get_tile("new",5,2),(0,0))
                self.minimap_terrains[T_DESK] = self.get_minimap_tile(1,0)
                self.terrains[(T_RUBBLE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_RUBBLE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_RUBBLE,w_code,f_code)].blit(self.get_tile("new",8,1),(0,0))
                self.minimap_terrains[T_RUBBLE] = self.get_minimap_tile(1,0)
                self.terrains[(T_DARK_ALTAR,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_DARK_ALTAR,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_DARK_ALTAR,w_code,f_code)].blit(self.get_tile("new",8,2),(0,0))
                self.minimap_terrains[T_DARK_ALTAR] = self.get_minimap_tile(1,0)
                self.terrains[(T_TABLE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_TABLE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_TABLE,w_code,f_code)].blit(self.get_tile("new",2,3),(0,0))
                self.minimap_terrains[T_TABLE] = self.get_minimap_tile(1,0)
                self.terrains[(T_STATUE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_STATUE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_STATUE,w_code,f_code)].blit(greyout(self.get_tile("gervais",12,4)),(0,0))
                self.minimap_terrains[T_STATUE] = self.get_minimap_tile(1,0)
                self.terrains[(T_THRONE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_THRONE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_THRONE,w_code,f_code)].blit(self.get_tile("new",3,2),(0,0))
                self.minimap_terrains[T_THRONE] = self.get_minimap_tile(0,0)
                self.terrains[(T_STOOL,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_STOOL,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_STOOL,w_code,f_code)].blit(self.get_tile("new",1,2),(0,0))
                self.minimap_terrains[T_STOOL] = self.get_minimap_tile(0,0)
                self.terrains[(T_GRAVESTONE,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_GRAVESTONE,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_GRAVESTONE,w_code,f_code)].blit(self.get_tile("new",6,4),(0,0))
                self.minimap_terrains[T_GRAVESTONE] = self.get_minimap_tile(0,0)
                self.terrains[(T_GRAVEYARD,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_GRAVEYARD,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_GRAVEYARD,w_code,f_code)].blit(self.get_tile("new",1,3),(0,0))
                self.minimap_terrains[T_GRAVEYARD] = self.get_minimap_tile(0,0) 
                self.terrains[(T_FOUNTAIN,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_FOUNTAIN,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_FOUNTAIN,w_code,f_code)].blit(self.get_tile("new",7,1),(0,0))
                self.minimap_terrains[T_FOUNTAIN] = self.get_minimap_tile(20,0)
                self.terrains[(T_SIGNPOST,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_SIGNPOST,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_SIGNPOST,w_code,f_code)].blit(self.get_tile("new",7,4),(0,0))
                self.minimap_terrains[T_SIGNPOST] = self.get_minimap_tile(21,0)
                self.terrains[(T_GRAVEMARKER,w_code,f_code)] = pygame.Surface((self.iconsize,self.iconsize))
                self.terrains[(T_GRAVEMARKER,w_code,f_code)].blit(self.tile_floor_underlays[f_code],(0,0))
                self.terrains[(T_GRAVEMARKER,w_code,f_code)].blit(self.get_tile("new",0,4),(0,0))
                self.minimap_terrains[T_GRAVEMARKER] = self.get_minimap_tile(20,0)
            # now things that depend on walls - should be more of these, if you start using it
            self.terrains[(T_WALL,W_ORDINARY,f_code)] = self.get_tile("gervais",0,22) 
            self.terrains[(T_WALL,W_WHITE,f_code)] = self.get_tile("gervais",0,26) 
            self.terrains[(T_WALL,W_WOOD,f_code)] = self.get_tile("gervais",0,25) 
            self.terrains[(T_WALL,W_BIGSTONE,f_code)] = self.get_tile("gervais",27,22)             
            self.terrains[(T_WALL,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",110,24)  
            self.minimap_terrains[T_WALL] = self.get_minimap_tile(1,0)                
            self.terrains[(T_LETTER,W_ORDINARY,f_code)] = self.get_tile("gervais",0,22) 
            self.terrains[(T_LETTER,W_WHITE,f_code)] = self.get_tile("gervais",0,26) 
            self.terrains[(T_LETTER,W_WOOD,f_code)] = self.get_tile("gervais",0,25) 
            self.terrains[(T_LETTER,W_BIGSTONE,f_code)] = self.get_tile("gervais",27,22)             
            self.terrains[(T_LETTER,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",110,24)  
            self.minimap_terrains[T_LETTER] = self.get_minimap_tile(1,0)     
            self.terrains[(T_STATUE_WALL,W_ORDINARY,f_code)] = self.get_tile("gervais",24,24) 
            self.terrains[(T_STATUE_WALL,W_WHITE,f_code)] = self.get_tile("gervais",0,24) 
            self.terrains[(T_STATUE_WALL,W_WOOD,f_code)] = self.get_tile("gervais",63,24) 
            self.terrains[(T_STATUE_WALL,W_BIGSTONE,f_code)] = self.get_tile("gervais",36,24)   
            self.terrains[(T_STATUE_WALL,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",38,24)              
            self.minimap_terrains[T_STATUE_WALL] = self.get_minimap_tile(1,0)                
            self.terrains[(T_DOOR,W_ORDINARY,f_code)] = self.get_tile("gervais",3,22) 
            self.terrains[(T_DOOR,W_WHITE,f_code)] = self.get_tile("gervais",31,26) 
            self.terrains[(T_DOOR,W_WOOD,f_code)] = self.get_tile("gervais",31,25) 
            self.terrains[(T_DOOR,W_BIGSTONE,f_code)] = self.get_tile("gervais",30,22)             
            self.terrains[(T_DOOR,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",30,22)             
            self.minimap_terrains[T_DOOR] = self.get_minimap_tile(2,0)   
            self.minimap_terrains[T_LOCKED_DOOR_GOLD] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_DOOR_RED] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_DOOR_BLUE] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_DOOR_GREEN] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_DOOR_SILVER] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_GATE_GOLD] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_GATE_RED] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_GATE_BLUE] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_GATE_GREEN] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_LOCKED_GATE_SILVER] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.minimap_terrains[T_GATE] = self.get_minimap_tile(22,0) # for large tile, uses the door tile with the key superimposed   
            self.terrains[(T_STAIRS_UP,W_ORDINARY,f_code)] = self.get_tile("gervais",15,22) 
            self.terrains[(T_STAIRS_UP,W_WHITE,f_code)] = self.get_tile("gervais",28,26) 
            self.terrains[(T_STAIRS_UP,W_WOOD,f_code)] = self.get_tile("gervais",28,25) 
            self.terrains[(T_STAIRS_UP,W_BIGSTONE,f_code)] = self.get_tile("gervais",42,22)             
            self.terrains[(T_STAIRS_UP,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",42,22)             
            self.minimap_terrains[T_STAIRS_UP] = self.get_minimap_tile(4,0)   
            self.terrains[(T_STAIRS_DOWN,W_ORDINARY,f_code)] = self.get_tile("gervais",16,22) 
            self.terrains[(T_STAIRS_DOWN,W_WHITE,f_code)] = self.get_tile("gervais",29,26) 
            self.terrains[(T_STAIRS_DOWN,W_WOOD,f_code)] = self.get_tile("gervais",29,25) 
            self.terrains[(T_STAIRS_DOWN,W_BIGSTONE,f_code)] = self.get_tile("gervais",43,22)             
            self.terrains[(T_STAIRS_DOWN,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",43,22)             
            self.minimap_terrains[T_STAIRS_DOWN] = self.get_minimap_tile(3,0)   
            self.terrains[(T_EXIT,W_ORDINARY,f_code)] = self.get_tile("gervais",13,22) 
            self.terrains[(T_EXIT,W_WHITE,f_code)] = self.get_tile("gervais",32,27) 
            self.terrains[(T_EXIT,W_WOOD,f_code)] = self.get_tile("gervais",32,25) 
            self.terrains[(T_EXIT,W_BIGSTONE,f_code)] = self.get_tile("gervais",40,22)             
            self.terrains[(T_EXIT,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",40,22)             
            self.minimap_terrains[T_EXIT] = self.get_minimap_tile(16,0)   
            self.terrains[(T_ENTRANCE,W_ORDINARY,f_code)] = self.get_tile("gervais",12,22) 
            self.terrains[(T_ENTRANCE,W_WHITE,f_code)] = self.get_tile("gervais",31,27) 
            self.terrains[(T_ENTRANCE,W_WOOD,f_code)] = self.get_tile("gervais",31,25) 
            self.terrains[(T_ENTRANCE,W_BIGSTONE,f_code)] = self.get_tile("gervais",39,22)             
            self.terrains[(T_ENTRANCE,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",39,22)             
            self.minimap_terrains[T_ENTRANCE] = self.get_minimap_tile(16,0)   
            self.terrains[(T_HOLE,W_ORDINARY,f_code)] = self.get_tile("gervais",16,22) 
            self.terrains[(T_HOLE,W_WHITE,f_code)] = self.get_tile("gervais",33,27) 
            self.terrains[(T_HOLE,W_WOOD,f_code)] = self.get_tile("gervais",33,25) 
            self.terrains[(T_HOLE,W_BIGSTONE,f_code)] = self.get_tile("gervais",82,22)             
            self.terrains[(T_HOLE,W_BIGSTONE_DARK,f_code)] = self.get_tile("gervais",82,22)             
            self.minimap_terrains[T_HOLE] = self.get_minimap_tile(15,0)   
        self.darkened_terrains = {} # create darkened versions - NOW ONLY ON DEMAND         
        self.temp_fire = self.get_tile("new",2,4)
        self.minimap_temp_fire = self.get_minimap_tile(18,0)
        self.letters = {}
        self.letters['A'] = self.get_tile("new",0,6)
        self.letters['B'] = self.get_tile("new",0,7)
        self.letters['C'] = self.get_tile("new",0,8)
        self.letters['D'] = self.get_tile("new",0,9)
        self.letters['E'] = self.get_tile("new",0,10)
        self.letters['F'] = self.get_tile("new",0,11)
        self.letters['G'] = self.get_tile("new",0,12)
        self.letters['H'] = self.get_tile("new",0,13)
        self.letters['I'] = self.get_tile("new",0,14)
        self.letters['J'] = self.get_tile("new",0,14)
        self.letters['K'] = self.get_tile("new",1,6)
        self.letters['L'] = self.get_tile("new",1,7)
        self.letters['M'] = self.get_tile("new",1,8)
        self.letters['N'] = self.get_tile("new",1,9)
        self.letters['O'] = self.get_tile("new",1,10)
        self.letters['P'] = self.get_tile("new",1,11)
        self.letters['Q'] = self.get_tile("new",1,12)
        self.letters['R'] = self.get_tile("new",1,13)
        self.letters['S'] = self.get_tile("new",2,8)
        self.letters['T'] = self.get_tile("new",2,9)
        self.letters['U'] = self.get_tile("new",2,10)
        self.letters['V'] = self.get_tile("new",2,11)
        self.letters['W'] = self.get_tile("new",2,12)
        self.letters['X'] = self.get_tile("new",2,13)
        self.letters['Y'] = self.get_tile("new",2,14)
        self.letters['Z'] = self.get_tile("new",2,15)
        self.exit_pictures = {}  
        self.exit_pictures[D_CAVE] = self.get_tile("new",2,7)
        self.exit_pictures[D_CROSSROADS] = self.get_tile("new",4,6)
        self.exit_pictures[D_CRYPT] = self.get_tile("new",4,5)
        self.exit_pictures[D_DROW] = self.get_tile("new",6,5)
        self.exit_pictures[D_EASY_DUNGEON] = self.get_tile("new",7,6)
        self.exit_pictures[D_FIREDRAKE] = self.get_tile("new",7,5)
        self.exit_pictures[D_GOBLIN_CAVE] = self.get_tile("new",5,6)
        self.exit_pictures[D_HALL_OF_CHAMPIONS] = self.get_tile("new",2,6)
        self.exit_pictures[D_HALL_OF_HEROES] = self.get_tile("new",6,6)
        self.exit_pictures[D_MAZE] = self.get_tile("new",3,6)
        self.exit_pictures[D_OUTSIDE] = self.get_tile("new",3,5)
        self.exit_pictures[D_QUIET_DUNGEON] = self.get_tile("new",8,6)
        self.exit_pictures[D_TREASURE_ROOM] = self.get_tile("new",8,7)
        self.exit_pictures[D_TREASURE_ROOM_2] = self.get_tile("new",5,5)
        self.exit_pictures[D_FIERY_PITS] = self.get_tile("new",2,4)
        # what room are we showing?
        self.last_room = None
        # Set time-since-zap-updated
        display.last_zap_update_at = pygame.time.get_ticks()
        display.last_message_update_at = pygame.time.get_ticks()
        self.last_character_hp = None
        # Record recent messages
        self.last_messages = []
        self.last_ambient_message = ""
        # Ambient message allowed?
        self.message_received = 0 # if this is >0, do not send an ambient message this turn
        # Have object and monster pics been filled in yet? (No)
        self.object_monster_pics_filled_in = 0
        
    def create_screen(self,width,height,name,fullscreen):
        icon = pygame.image.load("data/icon2.bmp")
        icon.set_colorkey(black)
        pygame.display.set_icon(icon) # TO DO - this is looking weird on the taskbar
        self.no_map_updates_yet = 1
        self.total_width = width
        self.total_height = height
        self.game_name = name
        if not pygame.display.mode_ok((self.total_width,self.total_height)):
            self.screen = pygame.display.set_mode((600,400))
            self.total_width = 600
            self.total_height = 400
            self.crash("Sorry, you need a higher resolution monitor to play the game (at least 1024x768)")
        max_screen_height = max(pygame.display.list_modes())[1]
        if fullscreen:
            self.do_fullscreenise() 
        else:
            self.do_windowise()
        pygame.display.set_caption(self.game_name)
    
    def do_windowise(self):
        self.is_fullscreen = 0
        self.screen = pygame.display.set_mode((self.total_width,self.total_height)) 
        self.button_fullscreenise_rect = Rect(self.total_width-16,3,12,12)
        self.button_quit_rect = None
        self.button_iconify_rect = None
        self.button_windowise_rect = None
        self.button_sound_rect = Rect(self.total_width-32,3,12,12)
        # still need to update display
        
    def do_fullscreenise(self):
        self.is_fullscreen = 1
        self.screen = pygame.display.set_mode((self.total_width,self.total_height),pygame.FULLSCREEN) 
        self.button_fullscreenise_rect = None
        self.button_iconify_rect = Rect(self.total_width-46,3,12,12)
        self.button_windowise_rect = Rect(self.total_width-31,3,12,12)
        self.button_quit_rect = Rect(self.total_width-16,3,12,12)
        self.button_sound_rect = Rect(self.total_width-61,3,12,12)
        # still need to update display

    def do_iconify(self):
        pygame.display.iconify()
        
    def simple_info_dialog(self,heading,text,image=None,allow_quit=0): # EXTERIOR USE
        GuilessDialog(heading,image,text,70,["OK"],None,is_fullscreen=self.is_fullscreen,allow_quit=allow_quit)

    def crash(self,message): # EXTERIOR USE
        self.simple_info_dialog("Error!",message)
        pygame.quit()
        sys.exit()        

    def blit_map_to_screen(self,force=0): # EXTERIOR USE
        # blit the map window only
        if force or self.need_to_blit: 
            self.screen.blit(self.map.view,(self.map.left,self.map.top))
            pygame.display.flip()
        self.need_to_blit = 0
            
    def blit_all_to_screen(self,d): # EXTERIOR USE
        # blit the whole thing
        self.screen.blit(self.background,(0,0))
        self.refill_character_pane(d)
        self.blit_map_to_screen(0)        
        self.message_area.draw()
        pygame.display.flip()

    def create_image_tile(self,tile_xy,new_tileset=0,from_col=None,to_col=None): # EXTERNAL USE
        # Pass back three tiles - one basic one, and another with no transparency, and a double-size one with no transparency
        if new_tileset:
            tileset = "new"
        else:
            tileset = "gervais"
        image = self.get_tile(tileset,tile_xy[0],tile_xy[1])
        if from_col is not None:
            image = colorchange(image,from_col,to_col)
        image_on_black = image.copy()
        big_image_on_black = scale_up_by(image,2)
        image_on_black.set_colorkey(None)
        big_image_on_black.set_colorkey(None) 
        return (image,image_on_black,big_image_on_black)     

    def get_tile(self,tileset,x,y):
        if tileset=="gervais":
            return get_tile(self.gervais_tiles,self.iconsize,x,y,black)
        elif tileset=="new":
            return get_tile(self.new_tiles,self.iconsize,x,y,black)
        
    def get_minimap_tile(self,x,y):
        return get_tile(self.minimap_tiles,self.minimap_iconsize,x,y,black)      

    def show_tile(self,tile,pos):
        # still need to call blit_map_to_screen
        self.map.view.blit(tile,self.rect_of_tile(pos.down,pos.right))

    def rect_of_tile(self,down,right):
        return Rect((self.iconsize*right+1,self.iconsize*down+1),(self.iconsize*(right+1),self.iconsize*(down+1)))

    def get_mouse_down_right(self,mouse_pos):
        # mouse_pos is from a Pygame mouse event
        if mouse_pos[1]>=self.map.top+self.map_rect.height or mouse_pos[1]<self.map.top:
            return None
        if mouse_pos[0]>=self.map.left+self.map_rect.width or mouse_pos[0]<self.map.left:
            return None
        down = (mouse_pos[1]-self.map.top-1)/self.iconsize
        right = (mouse_pos[0]-self.map.left-1)/self.iconsize
        return down,right

    def redraw_tile(self,d,pos,occupant):  # EXTERIOR USE
        if self.last_room is not None and not pos.same_room(self.last_room):
            return
        self.need_to_blit = 1
        self.draw_terrain(d,pos,0)
        if occupant is not None:
            self.draw_entity(d,pos,occupant)
            return
        self.draw_object(d,pos)
    
    def draw_black(self,d,pos):
        self.show_tile(self.black_tile,pos)
        
    def draw_terrain(self,d,pos,darkened=0):
        tile = d.l.tile_at(pos)
        if darkened:
            if tile.info().can_be_unlocked:
                key = (T_DOOR,tile.wall_type,tile.floor_type)
            elif tile.info().looks_like_floor and not tile.revealed:
                key = (T_FLOOR,tile.wall_type,tile.floor_type)
            else:
                key = (tile.type,tile.wall_type,tile.floor_type)
            if not(key in self.darkened_terrains):
                self.darkened_terrains[key] = darken(self.terrains[key],0.5)  
            self.show_tile(self.darkened_terrains[key],pos)
        else:
            if tile.info().can_be_unlocked:
                self.show_tile(self.terrains[(T_DOOR,tile.wall_type,tile.floor_type)],pos)
                if tile.info().key_type is not None:
                    self.show_tile(self.key_pics[tile.info().key_type],pos)
            elif tile.exit_to is not None:
                self.show_tile(self.terrains[(T_EXIT,tile.wall_type,tile.floor_type)],pos)
                exit_pic = self.exit_pictures.get(tile.exit_to[0],None)
                if exit_pic is not None:
                    self.show_tile(exit_pic,pos)
            elif tile.info().looks_like_floor and not tile.revealed:
                self.show_tile(self.terrains[(T_FLOOR,tile.wall_type,tile.floor_type)],pos)                
            else:
                self.show_tile(self.terrains[(tile.type,tile.wall_type,tile.floor_type)],pos)
        if d.l.is_temporary_fire(pos):
            self.show_tile(self.temp_fire,pos)
        if tile.info().is_letter:
            self.show_tile(self.letters[tile.message],pos)
    
    def draw_object(self,d,pos):
        tile = d.l.tile_at(pos)
        if tile.object is not None:
            self.show_tile(tile.object.info().tile,pos)

    def get_entity_tile(self,d,entity):
        if entity.is_character:
            if entity.has_condition(C_CHAMELEON):
                return partialize(self.character_tile,0.2)
            elif entity.has_condition(C_STONESKIN):
                return greyout(self.character_tile)
            elif entity.has_condition(C_SNEAKING):
                return darken(self.character_tile,0.5)
            elif entity.has_condition(C_CIRCLE_OF_PROTECTION):
                return self.overlay(self.goldstars,self.character_tile)
            else:
                return self.character_tile
        else:
            if entity.has_condition(C_BLESSED):
                return self.overlay(self.redstars,entity.info().tile)
            else:
                return entity.info().tile
            
    def draw_entity(self,d,pos,entity):
        if not entity.has_condition(C_INVISIBLE):
            self.show_tile(self.get_entity_tile(d,entity),entity.pos)

    def fade(self,d,entity):
        entity_tile = self.get_entity_tile(d,entity)
        for i in range(0,6):
            tile = partialize(entity_tile,(5-i)/5.0)
            self.draw_terrain(d,entity.pos,0)
            self.show_tile(tile,entity.pos)           
            self.draw_object(d,entity.pos)
            self.show_glyphs(d)
            self.blit_map_to_screen(1)
            wait(ms=40)
    
    def overlay(self,bottom_tile,top_tile):
        result = bottom_tile.copy()
        result.blit(top_tile,(0,0))
        return result
        
    def draw_flash(self,d,pos,tile,seconds):  # EXTERIOR USE
        if not pos.same_room(self.last_room):
            return
        former_contents = pygame.Surface((self.iconsize,self.iconsize))         
        former_contents.blit(self.map.view,(0,0),self.rect_of_tile(pos.down,pos.right))
        self.show_tile(tile,pos)
        self.show_glyphs(d)
        self.blit_map_to_screen(1)
        wait(ms=int(seconds*1000))
        self.map.view.blit(former_contents,self.rect_of_tile(pos.down,pos.right))
        self.show_glyphs(d)
        self.blit_map_to_screen(1)
        
    def draw_multiflash(self,d,posses,tile,seconds):  # EXTERIOR USE
        in_same_room = 0
        all_former_contents = []
        for pos in posses:
            if not pos.same_room(self.last_room):
                continue
            in_same_room = 1
            former_contents = pygame.Surface((self.iconsize,self.iconsize))         
            former_contents.blit(self.map.view,(0,0),self.rect_of_tile(pos.down,pos.right))
            all_former_contents.append(former_contents)
            self.show_tile(tile,pos)
        if not in_same_room:
            return
        self.show_glyphs(d)
        self.blit_map_to_screen(1)
        wait(ms=int(seconds*1000))
        for i in range(len(posses)):
            self.map.view.blit(all_former_contents[i],self.rect_of_tile(posses[i].down,posses[i].right))
        self.show_glyphs(d)
        self.blit_map_to_screen(1)        

    def refill_character_pane(self,d,hilite_missile=0):  # EXTERIOR USE
        character = d.get_character()
        # first items
        if character.garb is not None:
            self.screen.blit(character.garb.info().tile_on_black,self.garb_rect)
        else:
            self.screen.blit(self.black_tile,self.garb_rect)
        if character.melee_weapon is not None:
            self.screen.blit(character.melee_weapon.info().tile_on_black,self.melee_weapon_rect)
        else:
            self.screen.blit(self.black_tile,self.melee_weapon_rect)
        self.redraw_missile_weapon(d,hilite_missile=hilite_missile,update=0)
        for i in range(6):
            item = character.items[i]
            if item is not None:
                self.screen.blit(item.info().tile_on_black,self.item_rects[i])             
            else:
                self.screen.blit(self.black_tile,self.item_rects[i])     
        for i in range(5):
            key = character.keys[i]
            if key is not None:
                self.screen.blit(key.info().tile_on_black,self.key_rects[i],Rect(4,4,24,24))             
            else:
                self.screen.blit(self.black_tile,self.key_rects[i],Rect(4,4,24,24))  
        # then score
        pygame.draw.rect(self.screen, black, self.score_rect)
        message_surface = self.message_font.render(str(character.score), 1, white)
        self.screen.blit(message_surface,Rect(self.score_rect.left + self.score_rect.width - message_surface.get_width() - 3,self.score_rect.top,message_surface.get_width(),self.score_rect.left))
        # then buttons in top right corner
        if self.button_fullscreenise_rect is not None:
            self.screen.blit(self.fullscreenise,self.button_fullscreenise_rect)
        if self.button_iconify_rect is not None:
            self.screen.blit(self.iconify,self.button_iconify_rect)
        if self.button_windowise_rect is not None:
            self.screen.blit(self.windowise,self.button_windowise_rect)
        if self.button_quit_rect is not None:
            self.screen.blit(self.quit,self.button_quit_rect)
        if self.button_sound_rect is not None:
            if sound.use_sound == 1:
                self.screen.blit(self.soundon,self.button_sound_rect)
            else:
                self.screen.blit(self.mute,self.button_sound_rect)
        # then bars, and flip display
        self.redraw_bars(character,1)
    
    def redraw_missile_weapon(self,d,hilite_missile=0,update=1):
        character = d.get_character()
        if character.missile_weapon is not None:
            if hilite_missile:
                self.screen.blit(lighten(character.missile_weapon.info().tile_on_black,0.3,only_col=black),self.missile_weapon_rect)
            else:
                self.screen.blit(character.missile_weapon.info().tile_on_black,self.missile_weapon_rect)       
        else:
            self.screen.blit(self.black_tile,self.missile_weapon_rect)
        if update:
            pygame.display.update([self.missile_weapon_rect])
        
    def redraw_bars(self,character,force=0):
        if character.has_condition(C_POISONED):
            if character.c[C_POISONED].level==1:
                hp_color = muddy
            elif character.c[C_POISONED].level==2:
                hp_color = green
        else:
            hp_color = red
        redraw = force
        if self.last_character_hp is None:
            redraw = 1
        else:
            if self.last_character_hp<>character.hp or self.last_character_mp<>character.mp or abs(self.last_character_zap-character.zap)>=0.05 or self.last_hp_color<>hp_color:
                redraw = 1
        if not redraw:
            return
        self.last_character_hp = character.hp
        self.last_character_mp = character.mp
        self.last_character_zap = character.zap
        self.last_hp_color = hp_color
        self.draw_bar(self.hp_rect, float(character.hp)/character.original_hp, hp_color)
        self.draw_bar(self.mp_rect, float(character.mp)/character.original_mp, blue)
        self.draw_bar(self.energy_rect, float(character.zap)/character.original_zap, dark_grey)
        # pygame.display.flip()
        pygame.display.update([self.hp_rect,self.mp_rect,self.energy_rect])
        
    def draw_bar(self, rect, fraction, color):
        # used by the above
        barheight = max(1,(fraction)*rect.height)
        pygame.draw.rect(self.screen, black, rect)
        bar1_rect = Rect(rect.left,rect.bottom - barheight,rect.width,barheight+1)
        pygame.draw.rect(self.screen, (color[0]*0.5,color[1]*0.5,color[2]*0.5), bar1_rect)
        bar2_rect = Rect(rect.left+1,rect.bottom - barheight,rect.width-2,barheight+1)
        pygame.draw.rect(self.screen, (color[0]*0.8,color[1]*0.8,color[2]*0.8), bar2_rect)
        bar3_rect = Rect(rect.left+2,rect.bottom - barheight,rect.width-4,barheight+1)
        pygame.draw.rect(self.screen, color, bar3_rect)
    
    def flash_zap_bar(self,character,color):
        self.draw_bar(self.energy_rect, character.zap/character.original_zap, color)
        pygame.display.flip() 
        wait(ms=50)
        self.draw_bar(self.energy_rect, character.zap/character.original_zap, dark_grey)
        pygame.display.flip()        
        
    def send_message(self,text,junk=0):  # EXTERIOR USE
        if text=="":
            return
        self.message_received = 2 # 2 turns until an ambient message can be heard
        now = pygame.time.get_ticks()
        elapsed = now - display.last_message_update_at # ms
        require_elapsed = 100          
        if elapsed < require_elapsed:  
            wait(ms=require_elapsed-elapsed)
        display.last_message_update_at = now
        separated_text = []
        words = text.split(' ')
        line = ''
        size = 0
        for word in words:
            word_and_space = word + ' '
            word_size = display.message_font.render(word_and_space, 1, black).get_width()
            if word_size + size > (self.message_rect.width-10):
                separated_text.append(line)
                line = word_and_space
                size = word_size
            else:
                line = line + word_and_space
                size = size + word_size
        separated_text.append(line)
        self.last_messages.append(separated_text)
        self.message_area.show_message(separated_text,yellow)

    def show_message(self,separated_text,color):
        i = 0
        for line in separated_text:
            message_surface = self.message_font.render(line, 1, color)
            self.screen.blit(message_surface,(self.message_rect.left+5,self.message_rect.top+5+i*message_surface.get_height()))
            i = i + 1
        pygame.display.flip()
        
    def wait_for_input(self):
        done = 0
        while not done:
            events = pygame.event.get()
            for event in events:
                if event.type==KEYDOWN and event.key in [K_SPACE, K_RETURN, K_KP_ENTER, K_ESCAPE]:
                    done = 1
        
    def clear_map(self):  # EXTERIOR USE
        self.map.view.fill(black)

    def draw_map(self,d,fogged=0,pos_to_draw_at=None):  # EXTERIOR USE
        # a complete draw
        if pos_to_draw_at is None:
            active_pos = d.get_active_pos()
        else:
            active_pos = pos_to_draw_at
        room = d.l.room_at(active_pos)
        pos = Pos(room.level,room.r_down,room.r_right,0,0)
        for i in range(room.height): 
            pos.down = i
            for j in range(room.width):
                pos.right = j
                self.draw_terrain(d,pos,0)
                occupant = d.get_occupant(pos)
                if occupant is not None:
                    self.draw_entity(d,pos,occupant)
                    continue
                self.draw_object(d,pos)
        if fogged:
            for i in range(0,self.map._height):
                for j in range(i%2,self.map._width,2):
                    self.map.view.set_at((j,i),(150,150,150,255))
        self.need_to_blit = 1

    def move_view_to(self,d,pos,fogged=0):  # EXTERIOR USE
        if self.last_room is None or not self.last_room.same_room(pos):
            self.draw_map(d,pos_to_draw_at=pos,fogged=fogged)    
            self.show_glyphs(d)
            self.blit_map_to_screen()
            self.last_room = pos.copy()
        
    def draw_minimap(self,d,detect_enemies=0):  # EXTERIOR USE
        if detect_enemies:
            d.get_character().mp = d.get_character().mp - 6
            d.get_character().powers_used[P_DETECT_ENEMIES] = d.turn
        level = d.get_active_pos().level
        if d.l.levels[level].r_width > 5:
            leftmost_r_right = min(d.l.levels[level].r_width-5,max(0,d.get_active_pos().r_right-2))
        else:
            leftmost_r_right = 0
        if d.l.levels[level].r_height > 5:
            upmost_r_down = min(d.l.levels[level].r_height-5,max(0,d.get_active_pos().r_down-2))
        else:
            upmost_r_down = 0
        self.map.view.fill(black)
        room_top_y = 10-23*upmost_r_down
        for r_down in range(d.l.levels[level].r_height):
            y_increment = 0
            room_left_x = 5-23*leftmost_r_right
            for r_right in range(d.l.levels[level].r_width):
                room = d.l.levels[level].rooms[r_down][r_right]
                y_increment = max(y_increment,room.height)
                x_increment = room.width
                this_pos = Pos(level,r_down,r_right,0,0)
                if room.ever_visited:
                    for down in range(room.height):
                        for right in range(room.width):
                            this_pos.down = down
                            this_pos.right = right
                            if d.l.is_temporary_fire(this_pos):
                                minimap_tile = self.minimap_temp_fire
                            else:
                                minimap_tile = self.minimap_terrains[d.l.tile_at(this_pos).type]
                            rectangle = Rect((self.minimap_iconsize*(right+room_left_x)+1,self.minimap_iconsize*(down+room_top_y)+1),(self.minimap_iconsize*((right+room_left_x)+1),self.minimap_iconsize*((down+room_top_y)+1)))
                            self.map.view.blit(minimap_tile,rectangle)
                            if d.l.tile_at(this_pos).object is not None:
                                self.map.view.blit(self.minimap_object_tile,rectangle)
                            if d.get_active_pos().r_down==r_down and d.get_active_pos().r_right==r_right:
                                occupant = d.get_occupant(this_pos)
                                if occupant is not None:
                                    if occupant.is_character:
                                        self.map.view.blit(self.minimap_character_tile,rectangle)
                                    elif occupant.type==M_STATUE and not detect_enemies:
                                        self.map.view.blit(self.minimap_statue_tile,rectangle)
                                    elif occupant.type in (M_INVISIBLE_STALKER,M_CHAMELEON) and not detect_enemies:
                                        pass
                                    elif occupant.has_condition(C_INVISIBLE) and not detect_enemies:
                                        pass
                                    else:
                                        self.map.view.blit(self.minimap_monster_tile,rectangle)
                elif detect_enemies:
                    for down in range(room.height):
                        for right in range(room.width):
                            this_pos.down = down
                            this_pos.right = right
                            occupant = d.get_occupant(this_pos)
                            if occupant is not None:
                                rectangle = Rect((self.minimap_iconsize*(right+room_left_x)+1,self.minimap_iconsize*(down+room_top_y)+1),(self.minimap_iconsize*((right+room_left_x)+1),self.minimap_iconsize*((down+room_top_y)+1)))
                                self.map.view.blit(self.minimap_monster_tile,rectangle)                    
                room_left_x = room_left_x + x_increment
            room_top_y = room_top_y + y_increment                
        if not detect_enemies:
            text = self.message_font.render("Click to exit...",1,yellow)
        else:
            text = self.message_font.render("Red dots indicate enemies lying in wait.  Click to exit...",1,yellow)
        self.map.view.blit(text,Rect((0,0),(0,0)))
        self.show_glyphs(d)
        self.blit_map_to_screen(1)

    def info_popup(self,entity=None,object=None,tile=None,pickup_query=0,chardump_option=0): # EXTERIOR USE
        if object is not None:
            title = object.info().name
            text = object.info().description
            image = object.info().tile_on_black
            if object.info().slot == SL_GARB and entity is not None:
                text = text+'\n\nArmor: ' + str(entity.stats.armor)
                if len(entity.stats.armor_texts)>0:
                    text = text + "  ("
                    for this_text in entity.stats.armor_texts:
                        text = text + this_text + ", "
                    text = text[0:len(text)-2] + ")"
                text = text+'\nSpeed: ' + str(entity.stats.speed)
                if len(entity.stats.speed_texts)>0:
                    text = text + "  ("
                    for this_text in entity.stats.speed_texts:
                        text = text + this_text + ", "
                    text = text[0:len(text)-2] + ")"
                text = text+'\nMagic Resistance: ' + str(entity.stats.magic_resistance)
                if len(entity.stats.magic_resistance_texts)>0:
                    text = text + "  ("
                    for this_text in entity.stats.magic_resistance_texts:
                        text = text + this_text + ", "
                    text = text[0:len(text)-2] + ")"
                text = text+'\nStealth: ' + str(entity.stats.stealth)
                if len(entity.stats.stealth_texts)>0:
                    text = text + "  ("
                    for this_text in entity.stats.stealth_texts:
                        text = text + this_text + ", "
                    text = text[0:len(text)-2] + ")"
                text = text+'\n\n'
                for condition in entity.c.keys():
                    if condition<>C_FIRERES_FROM_SPELL and condition<>C_FIRERES_FROM_POTION:
                        text = text + entity.c[condition].get_type_string()+'\n'
                if entity.info().fire_immunity:
                    text = text + 'IMMUNE TO FIRE'+'\n'
                elif entity.info().fire_resistance:
                    text = text + 'RESISTANT TO FIRE'+'\n'
                if entity.info().protected_from_missiles:
                    text = text + 'PROTECTED FROM MISSILES'+'\n'
        elif entity is not None:
            title = sentencecase(entity.name)
            text = entity.popup_desc() 
            if not entity.is_character:
                title = title + "  (" + str(max(1,int(floor(entity.hp)))) + " HP)"
            image = entity.popup_image()   
            if entity.type==M_STATUE:
                title = "Dungeon feature"
                text = tlib.t[T_STATUE].desc
        elif tile is not None:
            title = "Dungeon feature"
            text = tile.info().description(tile.jammed,tile.exit_to)
            if tile.info().can_be_unlocked:
                image = pygame.Surface((self.iconsize,self.iconsize))
                image.blit(self.terrains[(T_DOOR,tile.wall_type,tile.floor_type)],(0,0))
                if tile.info().key_type is not None:
                    image.blit(self.key_pics[tile.info().key_type],(0,0))
            elif tile.exit_to is not None:
                image = pygame.Surface((self.iconsize,self.iconsize))
                image.blit(self.terrains[(T_EXIT,tile.wall_type,tile.floor_type)],(0,0))
                exit_pic = self.exit_pictures.get(tile.exit_to[0],None)
                if exit_pic is not None:
                    image.blit(exit_pic,(0,0))
            elif tile.info().looks_like_floor and not tile.revealed:
                image = pygame.Surface((self.iconsize,self.iconsize))
                image.blit(self.terrains[(T_FLOOR,tile.wall_type,tile.floor_type)],(0,0))
                text = "The dungeon floor, paved with flagstones."
            else:
                image = self.terrains[(tile.type,tile.wall_type,tile.floor_type)]
        if not pickup_query and not chardump_option:
            self.simple_info_dialog(title,text,image)
        elif chardump_option:
            return GuilessDialog(title,image,text,70,["OK","Chardump"],["o","c"],is_fullscreen=self.is_fullscreen)=="Chardump"
        elif pickup_query:
            return self.get_yes_no(title,text+"\n\nDo you want to pick it up?",image=image)

    def show_power(self,prefix,power_code,name,description,ask_to_dump=0): # EXTERIOR USE
        image = None # for now
        if ask_to_dump:
            dump = GuilessDialog(prefix + " " + name,image,description,70,["OK","Forget it!"],None,is_fullscreen=self.is_fullscreen)<>"OK"
            if dump and self.get_yes_no("Really forget a power?","Do you really want to forget the power of " + name + "? You would not be able to use it again..."):
                return 1
            return 0
        else:
            self.simple_info_dialog(prefix + " " + name,description,image)
        
    def get_yes_no(self,heading,text,image=None): # EXTERIOR USE
        return GuilessDialog(heading,image,text,70,["Yes","No"],["y","n"],is_fullscreen=self.is_fullscreen)=="Yes"

    def fill_in_object_pics(self,olib): # exterior use once only - make pictures for each object
        self.key_pics = {} # we'll fill this in too, for convenience
        for object_info_key in olib.o.keys():
            object_info = olib.o[object_info_key]
            object_info.tile, object_info.tile_on_black, object_info.big_tile_on_black = self.create_image_tile(object_info.tile_xy,new_tileset=object_info.new_tileset,from_col=object_info.from_col,to_col=object_info.to_col)
            if object_info.is_key:
                self.key_pics[object_info.type] = object_info.tile

    def fill_in_monster_pics(self,mlib): # exterior use once only - make pictures for each monster
        for monster_info_key in mlib.m.keys():
            monster_info = mlib.m[monster_info_key]
            if monster_info.new_tileset:
                tileset = "new"
            else:
                tileset = "gervais"
            monster_info.tile = self.get_tile(tileset,monster_info.tile_xy[0],monster_info.tile_xy[1])
            if monster_info.chameleon:
                monster_info.tile = partialize(monster_info.tile,0.3)
            if monster_info.from_color is not None:
                monster_info.tile = colorchange(monster_info.tile,monster_info.from_color,monster_info.to_color)
            if monster_info.monochrome:
                monster_info.tile = greyout(monster_info.tile)
                
    def show_glyphs(self,d):
        # blit not done here
        glyphs_latest_last = []
        for i in range(len(d.glyphs)):
            glyphs_latest_last.append(d.glyphs[len(d.glyphs)-i-1])
        click_counter = 1
        if len(glyphs_latest_last)==1 and is_click(glyphs_latest_last[0]):
            return
        while len(glyphs_latest_last)>0:
            if click_counter>9:
                break
            while len(glyphs_latest_last)>0 and (mouse_pos_to_map_pos(d,self,glyphs_latest_last[0].last_pos) is None):
                glyphs_latest_last = glyphs_latest_last[1:]
            if len(glyphs_latest_last)==0:
                break
            if len(glyphs_latest_last)>=3:
                if is_triple_click(glyphs_latest_last[0],glyphs_latest_last[1],glyphs_latest_last[2]):
                    self.plot_multi_star(d,3,glyphs_latest_last[0].last_pos,click_counter)
                    glyphs_latest_last = glyphs_latest_last[3:]
                    click_counter = click_counter + 3
                    self.need_to_blit=1
                    continue
            if len(glyphs_latest_last)>=2:
                if is_double_click(glyphs_latest_last[0],glyphs_latest_last[1]):
                    self.plot_multi_star(d,2,glyphs_latest_last[0].last_pos,click_counter)
                    glyphs_latest_last = glyphs_latest_last[2:]
                    click_counter = click_counter + 2
                    self.need_to_blit=1
                    continue       
            if is_click(glyphs_latest_last[0]):
                self.plot_multi_star(d,1,glyphs_latest_last[0].last_pos,click_counter)
                glyphs_latest_last = glyphs_latest_last[1:]
                click_counter = click_counter + 1
                self.need_to_blit=1
                continue
            elif mouse_pos_to_map_pos(d,display,glyphs_latest_last[0].first_pos) is not None:
                self.plot_drag(d,glyphs_latest_last[0].pos_series)
                self.plot_multi_star(d,1,glyphs_latest_last[0].first_pos,click_counter)
                glyphs_latest_last = glyphs_latest_last[1:]
                click_counter = click_counter + 1
                self.need_to_blit=1
                continue
            else:
                click_counter = click_counter + 1
                continue
            
    def plot_drag(self,d,mouse_pos_series):
        # mouse_pos_series is a [(right,down)]
        # blit not done here
        # initial star not done here
        for i in range(0,len(mouse_pos_series)-1):
            start_down = mouse_pos_series[i][1] - self.map.top
            start_right = mouse_pos_series[i][0] - self.map.left
            end_down = mouse_pos_series[i+1][1] - self.map.top
            end_right = mouse_pos_series[i+1][0] - self.map.left           
            pygame.draw.line(self.map.view, yellow, (start_right,start_down), (end_right,end_down))
        
    def plot_multi_star(self,d,n_stars,right_down,number_in_stars):
        # blit not done here
        if n_stars==1:
            image = self.one_star
            separate_numbers = 0
        elif n_stars==2:
            image = self.two_stars
            separate_numbers = 8
        elif n_stars==3:
            image = self.three_stars
            separate_numbers = 6
        top = right_down[1] - image.get_height()/2 - self.map.top
        left = right_down[0] - image.get_width()/2 - self.map.left
        self.map.view.blit(image,(left,top))
        for i in range(number_in_stars,number_in_stars+n_stars):
            text_image = self.smaller_message_font.render(str(i), 1, black)
            top = right_down[1] - text_image.get_height()/2 - self.map.top 
            left = right_down[0] - text_image.get_width()/2 - self.map.left + (i - (number_in_stars + (n_stars-1)/2.0)) * separate_numbers
            self.map.view.blit(text_image,(left,top))

def show_highscores(scores,names,surviveds): # exterior use
  texts = "These are the mighty champions of the past!\n\nScore          Name\n"
  for i in range(len(scores)):
    texts = texts + str(int(scores[i])) + '          ' + names[i] + '\n'
  display.simple_info_dialog('Hall of Heroes',texts,display.temple)
  
# do some psyco bindings 
psyco.bind(Screen_info.blit_map_to_screen)
psyco.bind(Screen_info.draw_bar)
psyco.bind(Screen_info.draw_map)
psyco.bind(Screen_info.move_view_to)
psyco.bind(Screen_info.redraw_bars)
psyco.bind(Screen_info.show_tile)
psyco.bind(Screen_info.fill_in_object_pics)
psyco.bind(Screen_info.initialise)

display = Screen_info()
